{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# Tree Structure Provider Example"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "The [Tree Structure Provider](https://plugins.jetbrains.com/docs/intellij/tree-structure-view.html) allows modifying the structure of the project tree in the Project View panel.\n",
    "\n",
    "Let's create a provider that will limit the presented files to the Plain Text files only. It will check if a Project View node represents a directory or file of the [`PlainTextFileType`](https://github.com/JetBrains/intellij-community/blob/master/platform/core-impl/src/com/intellij/openapi/fileTypes/PlainTextFileType.java) type. Otherwise, an element is not included in the results list, so only directories and plain text files are rendered."
   ]
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Enabling Kotlin Notebook Intellij Platform Integration\n",
    "\n",
    "Firstly, let's enable IntelliJ Platform integration and load necessary libraries."
   ]
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": "%use intellij-platform",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Extension Point\n",
    "\n",
    "We will implement the [`com.intellij.treeStructureProvider`](https://plugins.jetbrains.com/intellij-platform-explorer/extensions?extensions=com.intellij.postStartupActivity&extensions=com.intellij.treeStructureProvider) Extension Point, which allows modifying the structure of the project tree in the Project View panel."
   ]
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "import com.intellij.ide.projectView.TreeStructureProvider\n",
    "import com.intellij.ide.projectView.ViewSettings\n",
    "import com.intellij.ide.projectView.impl.nodes.PsiFileNode\n",
    "import com.intellij.ide.util.treeView.AbstractTreeNode\n",
    "import com.intellij.openapi.fileTypes.PlainTextFileType\n",
    "import org.jetbrains.annotations.Unmodifiable\n",
    "\n",
    "class TextOnlyTreeStructureProvider : TreeStructureProvider {\n",
    "    override fun modify(parent: AbstractTreeNode<*>, children: Collection<AbstractTreeNode<*>?>, settings: ViewSettings?) =\n",
    "        children.filter {\n",
    "            if (it is PsiFileNode) {\n",
    "                val file = it.virtualFile\n",
    "                file == null || file.isDirectory || file.fileType == PlainTextFileType.INSTANCE\n",
    "            } else {\n",
    "                true\n",
    "            }\n",
    "        }\n",
    "}"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Registering the Extension Point\n",
    "\n",
    "Let's create an instance of this provider.\n",
    "\n",
    "Since the extension point `com.intellij.treeStructureProvider` is marked as *project level*, we cannot use the `registerExtension` function. To maintain the proper scope, need to use the `registerProjectExtension` that will correctly associate the extension with the current project. This function is provided by the Kotlin Notebook IntelliJ Platform Integration."
   ]
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "import com.intellij.openapi.application.ApplicationManager\n",
    "import com.intellij.openapi.extensions.ProjectExtensionPointName\n",
    "\n",
    "runInEdt {\n",
    "    val treeStructureProvider = TextOnlyTreeStructureProvider()\n",
    "    registerProjectExtension(\"com.intellij.treeStructureProvider\", treeStructureProvider)\n",
    "}"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Running the Example\n",
    "\n",
    "If we run this example, we will observe that the Project tool window and its tree will display only plain-text files and directories. For example, the `LICENSE` file will be shown.\n",
    "\n",
    "In addition, the proper lifecycle of extensions is automatically maintained. Kotlin Notebook kernel restart will correctly dispose the project extension and restore the original full Project tool window tree.\n",
    "\n",
    "## Summary\n",
    "\n",
    "- Use `TreeStructureProvider` subclass to create the corresponding extension.\n",
    "- Discover the proper scope of the extension point in the [IntelliJ Platform Plugin SDK](https://plugins.jetbrains.com/docs/intellij/intellij-platform-extension-point-list.html#intellijsettingssynccorexml). Project level extension points need to be registered by `registerProjectExtension` function.\n",
    "- The lifecycle of the extension is automatically maintained.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Kotlin",
   "language": "kotlin",
   "name": "kotlin"
  },
  "language_info": {
   "name": "kotlin",
   "version": "2.2.20-dev-4982",
   "mimetype": "text/x-kotlin",
   "file_extension": ".kt",
   "pygments_lexer": "kotlin",
   "codemirror_mode": "text/x-kotlin",
   "nbconvert_exporter": ""
  },
  "ktnbPluginMetadata": {
   "sessionRunMode": "IDE_PROCESS"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
